from django.conf import settings
from django.shortcuts import redirect, render
from django.http import JsonResponse
from django.utils.deprecation import MiddlewareMixin
import re


class RBACMiddleware(MiddlewareMixin):
    """
    检查用户的url请求是否在权限范围内
    """

    def process_request(self, request):
        request_url = request.path_info
        permission_url = request.session.get(settings.SESSION_PERMISSION_URL_KEY)
        method = request.method
        # print(method)
        # 白名单内的url直接放行
        for url in settings.SAFE_URL:
            if re.match(url, request_url):
                return None
        # print("RBAC permission url: %s " % permission_url)
        # 没有检测到session中的url 相关配置则重定向到登录页面，登录的url页面在settings中设置
        if not permission_url:
            print('没有检测到permission_url,跳转到登录页面！')
            # 如果是从其他链接路径被跳转到登录页面，需要指定跳转地址，方便后续自动跳转页面
            if request.get_full_path():
                return redirect(settings.LOGIN_URL + '?next=' + request.get_full_path())
            else:
                return redirect(settings.LOGIN_URL)

        flag = False
        # 循环检查是否有匹配的权限地址
        for url in permission_url:
            url_pattern = settings.REGEX_URL.format(url=url['url'])
            now_method = url['method']
            if re.match(url_pattern, request_url) and method in now_method:
                flag = True
                break

        url_list = []
        for url in permission_url:
            url_list.append(url['url'])

        if flag:
            return None
        else:
            if settings.DEBUG:
                info = '无权限访问此接口：%s 的 %s 方法，请联系管理员！有权限的url：%s' % (request_url, method, url_list)
                if method == 'GET':
                    return render(request, 'error.html', {'message': info}, status=403)
                else:
                    code = 403
                    message = {
                        'code': code,
                        'msg': info
                    }
                    return JsonResponse(message)
            else:
                if method == 'GET':
                    return render(request, 'error.html', {'message': '无权限访问'}, status=403)
                else:
                    code = 403
                    message = {
                        'code': code,
                        'msg': '无权限访问，请联系管理员'
                    }
                    return JsonResponse(message)
